/**
 * 重置组件中的reactive对象
 * @param reactive对象
 *
 */

export const resetReactiveObject = (data, value = undefined) => {
  Object.keys(data).forEach((key) => {
    data[key] = value
  })
}

export const downloadFile = (fileName, url) => {
  if (!url) {
    return
  }
  const link = document.createElement('a')
  link.href = url
  link.download = fileName
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

export const previewFile = (url) => {
  if (!url) {
    return
  }
  const link = document.createElement('a')
  link.href = url
  link.target = '_blank'
  link.click()
}

/**
 * 随机生成固定位数或者一定范围内的字符串数字组合
 * @param {number} min 范围最小值
 * @param {number} max 范围最大值，当不传递时表示生成指定位数的组合
 * @returns {string} 返回字符串结果
 */
export function randomRange(min, max) {
  let returnStr = ''
  const range = max ? Math.round(Math.random() * (max - min)) + min : min
  const arr = [
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'l',
    'm',
    'n',
    'o',
    'p',
    'q',
    'r',
    's',
    't',
    'u',
    'v',
    'w',
    'x',
    'y',
    'z',
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G',
    'H',
    'I',
    'J',
    'K',
    'L',
    'M',
    'N',
    'O',
    'P',
    'Q',
    'R',
    'S',
    'T',
    'U',
    'V',
    'W',
    'X',
    'Y',
    'Z',
  ]

  for (let i = 0; i < range; i++) {
    const index = Math.round(Math.random() * (arr.length - 1))
    returnStr += arr[index]
  }
  return returnStr
}

export function getParametricEquation(
  startRatio,
  endRatio,
  isSelected,
  isHovered,
  k,
  h,
) {
  // 计算
  const midRatio = (startRatio + endRatio) / 2
  const startRadian = startRatio * Math.PI * 2
  const endRadian = endRatio * Math.PI * 2
  const midRadian = midRatio * Math.PI * 2
  // 如果只有一个扇形，则不实现选中效果。
  if (startRatio === 0 && endRatio === 1) {
    isSelected = false
  }
  // 通过扇形内径/外径的值，换算出辅助参数 k（默认值 1/3）
  k = typeof k !== 'undefined' ? k : 1 / 3
  // 计算选中效果分别在 x 轴、y 轴方向上的位移（未选中，则位移均为 0）
  const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0
  const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0
  // 计算高亮效果的放大比例（未高亮，则比例为 1）
  const hoverRate = isHovered ? 1.05 : 1
  // 返回曲面参数方程
  return {
    u: {
      min: -Math.PI,
      max: Math.PI * 3,
      step: Math.PI / 32,
    },
    v: {
      min: 0,
      max: Math.PI * 2,
      step: Math.PI / 20,
    },
    x(u, v) {
      if (u < startRadian) {
        return (
          offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
        )
      }
      if (u > endRadian) {
        return (
          offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
        )
      }
      return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate
    },
    y(u, v) {
      if (u < startRadian) {
        return (
          offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
        )
      }
      if (u > endRadian) {
        return (
          offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
        )
      }
      return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate
    },
    z(u, v) {
      if (u < -Math.PI * 0.5) {
        return Math.sin(u)
      }
      if (u > Math.PI * 2.5) {
        return Math.sin(u) * h * 0.1
      }
      return Math.sin(v) > 0 ? 1 * h * 0.1 : -1
    },
  }
}
// 根据指定字典值和列表查询文本
export const getLabelFromDictValue = (value, list, labelField = 'label', valueField = 'value') => list?.filter(item => item[valueField] === value)?.[0]?.[labelField] || ''

export const treeToList = (tree, result = [], level = 0) => {
  tree.forEach((node) => {
    result.push(node)
    node.level = level + 1
    node.children && treeToList(node.children, result, level + 1)
  })
  return result
}

export const getItemFromTree = (value, tree, key = 'id') => treeToList(tree).filter(item => item[key] === value)?.[0]

export const getResultData = (data, type) => {
  switch (type) {
    case 'total':
      return data.length
        ? data.filter(item => item.type === '事件数量')?.[0]?.amount || 0
        : 0
    case 'finish':
      return data.length
        ? data.filter(item => item.type === '已处理')?.[0]?.amount || 0
        : 0
    case 'unfinish':
      return data.length
        ? data.filter(item => item.type === '未处理')?.[0]?.amount || 0
        : 0
  }
}

export function formatNumberPointToTwo(num, point = 2) {
  if (!num) {
    num = 0
  }
  return String(num)?.includes('.') ? Number.parseFloat(num).toFixed(point) : num
}

export function filterTreeNodes(nodes, filterFn) {
  return nodes.map((node) => {
    const newNode = { ...node }
    if (newNode.children) {
      const res = filterTreeNodes(newNode.children, filterFn)
      if (res.length)
        newNode.children = res
      else delete newNode.children
    }
    return newNode
  }).filter(node => filterFn(node) || (node.children && node.children.length > 0))
}

// prop：对象数组排序的键，
// align：排序方式，"positive"正序，"inverted"倒序 ;eg// data.sort(compare('time','inverted'));
export function sortArrByTime(prop, align) {
  return function (a, b) {
    let value1 = a[prop]
    let value2 = b[prop]
    if (align === 'positive') {
      // 正序
      return new Date(value1) - new Date(value2)
    }
    else if (align === 'inverted') {
      // 倒序
      return new Date(value2) - new Date(value1)
    }
  }
}

export const formatUnit = (val) => {
  if (!val)
    return 0
  if (val < 10000) {
    return val
  }
  return `${(val / 10000).toFixed(1)}`
}
/**
 * 数组、数组对象去重
 * @param arr 数组内容
 * @param attr 需要去重的键值（数组对象）
 * @returns
 */
export function removeDuplicate(arr, attr) {
  if (!Object.keys(arr).length) {
    return arr
  }
  else {
    if (attr) {
      const obj = {}
      return arr.reduce((cur, item) => {
        obj[item[attr]] ? '' : (obj[item[attr]] = true && item[attr] && cur.push(item))
        return cur
      }, [])
    }
    else {
      return [...new Set(arr)]
    }
  }
}

/**
 * 判断两数组字符串是否相同（用于按钮权限验证），数组字符串中存在相同时会自动去重（按钮权限标识不会重复）
 * @param news 新数据
 * @param old 源数据
 * @returns 两数组相同返回 `true`，反之则反
 */
export function judgementSameArr(newArr, oldArr) {
  const news = removeDuplicate(newArr)
  const olds = removeDuplicate(oldArr)
  let count = 0
  const leng = news.length
  for (let i in olds) {
    for (let j in news) {
      if (olds[i] === news[j])
        count++
    }
  }
  return count === leng
}
export const flat = (arr, res = []) => {
  if (!arr?.length)
    return []
  arr.forEach((v) => {
    if (v.children && v.children.length) {
      res.push(v)
      res = res.concat(flat(v.children, res))
    }
    else {
      res.push(v)
    }
  })
  return Array.from(new Set(res))
}
